﻿/// <summary>
/// FileName: FunctionsExtension.cs
/// Author: Jiang Xiaolong
/// Created Time: 2015.05.12
/// Version: 1.0
/// Company: Sunnytech
/// Function: 自定义数学函数扩展，可以用以下方式扩展相应数学函数，TODO：不定参数个数函数；
///
/// Changed By:
/// Modification Time:
/// Discription:
/// </summary>
using System.Collections.Generic;
using System;
using Expression.api;

namespace Expression.impl
{
	//SIN函数，PI是系统默认常量，可以直接使用PI；
	public class SIN : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Sin函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Sin(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//ASIN函数，PI是系统默认常量，可以直接使用PI；
	public class ASIN : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Sin函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Asin(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//COS函数，PI是系统默认常量，可以直接使用PI；
	public class COS : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Cos函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Cos(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//ACOS函数，PI是系统默认常量，可以直接使用PI；
	public class ACOS : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Cos函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Acos(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//TAN函数，PI是系统默认常量，可以直接使用PI；
	public class TAN : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Tan函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Tan(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//ATAN函数，PI是系统默认常量，可以直接使用PI；
	public class ATAN : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Atan函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Atan(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//POW函数，指数函数，需要有两个参数；
	public class POW : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value1 = 0d;
			try
			{
				value1 = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Pow函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			double value2 = 0d;
			try
			{
				value2 = double.Parse(args[1].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Pow函数中不能填写类型为" + args[1].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Pow(value1, value2);
		}

		public int ParameterNumber()
		{
			return 2;
		}
	}

	//ln以e为底的自然对数函数，EULER是系统默认常量，可以直接使用EULER，代表自然对数e；
	public class LN : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}
		
		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>ln对数函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Log(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//lg以10为底的对数函数；
	public class LG : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>lg对数函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Log10(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//log函数有两个参数，后一个参数为底，注意不能为0或者负数，不然会返回错误；
	public class LOG : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value1 = 0d;
			try
			{
				value1 = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Log函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			double value2 = 0d;
			try
			{
				value2 = double.Parse(args[1].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Log函数中不能填写类型为" + args[1].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Log(value1, value2);
		}

		public int ParameterNumber()
		{
			return 2;
		}
	}

	//sqrt开根号函数；
	public class SQRT : ICustomFunction
	{
		public Type ExpType
		{
			get { return typeof(double); }
			set { }
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			double value = 0d;
			try
			{
				value = double.Parse(args[0].Evaluate().ToString());
			}
			catch
			{
				UnityEngine.Debug.LogError("错误>>>Sqrt函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
				return null;
			}
			return Math.Sqrt(value);
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//Abs取绝对值函数
	public class ABS : ICustomFunction
	{
		public Type ExpType
		{
			get { return _expType; }
			set { _expType = value; }
		}
		private Type _expType;

		public object Evaluate(List<ExpressionTree> args)
		{
			if (args[0].ExpType == typeof(double))
			{
				double value = 0d;
				try
				{
					value = double.Parse(args[0].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>ABS函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
					return null;
				}
				_expType = typeof(double);
				return Math.Abs(value);
			}
			else if (args[0].ExpType == typeof(float))
			{
				float value = 0f;
				try
				{
					value = float.Parse(args[0].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>ABS函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
					return null;
				}
				_expType = typeof(float);
				return Math.Abs(value);
			}
			else
			{
				int value = 0;
				try
				{
					value = int.Parse(args[0].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>ABS函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
					return null;
				}
				_expType = typeof(int);
				return Math.Abs(value);
			}
		}

		public int ParameterNumber()
		{
			return 1;
		}
	}

	//Random随机数生成函数，有两个参数，返回int或者double；
	public class RANDOM : ICustomFunction
	{
		public Type ExpType
		{
			get { return _expType; }
			set { _expType = value; }
		}
		private Type _expType;

		private Random _random;

		public RANDOM()
		{
			_random = new Random();
		}

		public object Evaluate(List<ExpressionTree> args)
		{
			if (args[0].ExpType == typeof(double) || args[0].ExpType == typeof(float) || args[1].ExpType == typeof(double) || args[1].ExpType == typeof(float))
			{
				double value1 = 0d;
				try
				{
					value1 = double.Parse(args[0].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>RANDOM函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
					return null;
				}
				double value2 = 0d;
				try
				{
					value2 = double.Parse(args[1].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>RANDOM函数中不能填写类型为" + args[1].ExpType.ToString() + "的参数！");
					return null;
				}
				_expType = typeof(double);
				return _random.NextDouble() * (value2 - value1) + value1;
			}
			else
			{
				int value1 = 0;
				try
				{
					value1 = int.Parse(args[0].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>RANDOM函数中不能填写类型为" + args[0].ExpType.ToString() + "的参数！");
					return null;
				}
				int value2 = 0;
				try
				{
					value2 = int.Parse(args[1].Evaluate().ToString());
				}
				catch
				{
					UnityEngine.Debug.LogError("错误>>>RANDOM函数中不能填写类型为" + args[1].ExpType.ToString() + "的参数！");
					return null;
				}
                _expType = typeof(int);
				return _random.Next(value1, value2);
			}
		}

		public int ParameterNumber()
		{
			return 2;
		}
	}
}

